package vn.bus.bk.place;

import java.util.ArrayList;

import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.MenuItem;

import vn.bus.bk.R;
import vn.bus.bk.adapter.ListBusAdapter;
import vn.bus.bk.adapter.ListPlaceAdapter;
import vn.bus.bk.adapter.ListTwoPlaceAdapter;
import vn.bus.bk.adapter.SQLiteAdapter;
import vn.bus.bk.dialog.DialogMessage;
import vn.bus.bk.object.BusHolder;
import vn.bus.bk.object.BusInfo;
import vn.bus.bk.object.BusTwoRouteInfo;
import vn.bus.bk.object.PlaceAndType;
import vn.bus.bk.other.Convert;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;

public class ListPlaceForAType extends SherlockListActivity {
    public static String typePlace;
    private SQLiteAdapter sqliteAdapter;
    private Cursor mCursor;
    private ArrayList<PlaceAndType> arrayListPlace;
    ListPlaceAdapter adapter;
    private int iNamePlace, iTypePlace, iStreetsPlace;
    private String[] columnsPlace = { "name", "type", "streets" };
    private String streets;
    private ArrayList<BusInfo> myListBus;
    private ListBusAdapter myBusAdapter;
    private ListTwoPlaceAdapter myTwoPlaceAdapter;
    private String startPlace;

    private ArrayList<BusHolder> listForFirst, listForLast;
    private ArrayList<BusTwoRouteInfo> listForTwoPlace;

    private int iNumber, iGoBus, iBackBus, iName, iTimeStartBus, iTimeEndBus,
	    iFrequency, iValue, iOrdinateGo, iOrdinateBack;
    private String[] columnsBus;
    private DisplayMetrics metrics;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	// TODO Auto-generated method stub
	super.onCreate(savedInstanceState);
	columnsBus = getResources().getStringArray(R.array.arrayColumn);
	sqliteAdapter = new SQLiteAdapter(this);
	getSupportActionBar().setDisplayHomeAsUpEnabled(true);
	getSupportActionBar().setHomeButtonEnabled(true);
	
	metrics = new DisplayMetrics();
	getWindowManager().getDefaultDisplay().getMetrics(metrics);
	loadListFromDatabase();
	setup();
    }

    private void loadListFromDatabase() {
	// TODO Auto-generated method stub
	arrayListPlace = new ArrayList<PlaceAndType>();
	sqliteAdapter = new SQLiteAdapter(this);
	try {
	    sqliteAdapter.close();
	    sqliteAdapter.copyDataBase();
	    sqliteAdapter.openDataBase();

	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    Log.i("DATABASE", "Cannot connect to database");
	}
	try {

	    mCursor = sqliteAdapter.rawAllPlace();
	    mCursor.moveToFirst();
	    initialzeIndexForPlaceTable();

	    do {
		if (mCursor.getString(iTypePlace).equals(typePlace)) {
		    arrayListPlace.add(new PlaceAndType(mCursor
			    .getString(iNamePlace), mCursor
			    .getString(iTypePlace), mCursor
			    .getString(iStreetsPlace)));
		}

		mCursor.moveToNext();
	    } while (!mCursor.isAfterLast());

	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	sqliteAdapter.close();
    }

    private void setup() {
	ArrayList<String> listPlaceString = new ArrayList<String>();
	for (int i = 0; i < arrayListPlace.size(); i++) {
	    listPlaceString.add(arrayListPlace.get(i).getName());
	}
//	adapter = new ArrayAdapter<String>(ListPlaceForAType.this,
//		android.R.layout.simple_list_item_1, listPlaceString);
//	
	adapter = new ListPlaceAdapter(this, listPlaceString, metrics); 
	setListAdapter(adapter);
	Log.i("SIZE LIST", String.valueOf(adapter.getCount()));

    }

    private void initialzeIndexForPlaceTable() {
	// TODO Auto-generated method stub
	iNamePlace = mCursor.getColumnIndex(columnsPlace[0]);
	iTypePlace = mCursor.getColumnIndex(columnsPlace[1]);
	iStreetsPlace = mCursor.getColumnIndex(columnsPlace[2]);

    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
	// TODO Auto-generated method stub
	super.onListItemClick(l, v, position, id);
	LayoutInflater li = LayoutInflater.from(this);
	View view = li.inflate(R.layout.prompt, null);
	// get a builder and set the view
	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	builder.setTitle(getString(R.string.first_place_iput));
	builder.setView(view);
	final EditText et = (EditText) view.findViewById(R.id.etPlaceStart);
	streets = arrayListPlace.get(position).getStreets();
	builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

	    public void onClick(DialogInterface arg0, int arg1) {
		// TODO Auto-generated method stub
		startPlace = et.getText().toString();
		if (startPlace.trim().length() != 0) {
		    loadDataFromDatabase();

		    FindOneAsynTask taskFindOne = new FindOneAsynTask(
			    ListPlaceForAType.this);
		    taskFindOne.execute("FindOne");
		}
	    }
	});

	builder.setNegativeButton(getString(R.string.cancel),
		new DialogInterface.OnClickListener() {

		    public void onClick(DialogInterface arg0, int arg1) {
			// TODO Auto-generated method stub

		    }
		});

	builder.show();

    }

    private boolean findBus() {
	String[] allStreet = streets.split("-");
	startPlace = standardizeInput(startPlace);
	startPlace = startPlace.trim();
	myListBus = new ArrayList<BusInfo>();
	for (int i = 0; i < allStreet.length; i++) {
	    String last = allStreet[i];
	    last = last.trim();
	    last = last.toLowerCase();
	    findOneRoute(startPlace, last);
	}
	if (myListBus.size() == 0) {
	    return false;
	} else {
	    myBusAdapter = new ListBusAdapter(this, myListBus);
	    sqliteAdapter.close();
	    return true;
	}

    }

    private void findOneRoute(String first, String last) {

	try {
	    mCursor.moveToFirst();

	    do {
		String go = standardizeRoute(mCursor.getString(iGoBus));
		String back = standardizeRoute(mCursor.getString(iBackBus));
		if (check(first, go) && check(last, go)) {
		    if (go.indexOf(first) < go.indexOf(last)) {
			myListBus.add(new BusInfo(mCursor.getInt(iNumber),
				mCursor.getString(iName), mCursor
					.getString(iGoBus), mCursor
					.getString(iBackBus), mCursor
					.getString(iTimeStartBus), mCursor
					.getString(iTimeEndBus), mCursor
					.getString(iFrequency), mCursor
					.getString(iValue), mCursor
					.getString(iOrdinateGo), mCursor
					.getString(iOrdinateBack)));
		    }
		}
		if (check(first, back) && check(last, back)) {
		    if (back.indexOf(first) < back.indexOf(last)) {
			myListBus.add(new BusInfo(mCursor.getInt(iNumber),
				mCursor.getString(iName), mCursor
					.getString(iGoBus), mCursor
					.getString(iBackBus), mCursor
					.getString(iTimeStartBus), mCursor
					.getString(iTimeEndBus), mCursor
					.getString(iFrequency), mCursor
					.getString(iValue), mCursor
					.getString(iOrdinateGo), mCursor
					.getString(iOrdinateBack)));
		    }
		}
		mCursor.moveToNext();
	    } while (!mCursor.isAfterLast());

	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

    }

    private boolean findTwoRoute() {
	String[] allStreet = streets.split("-");
	startPlace = standardizeInput(startPlace);
	startPlace = startPlace.trim();
	listForFirst = new ArrayList<BusHolder>();
	listForLast = new ArrayList<BusHolder>();
	listForTwoPlace = new ArrayList<BusTwoRouteInfo>();
	for (int i = 0; i < allStreet.length; i++) {
	    String last = allStreet[i];
	    last = last.trim().toLowerCase();
	    createTwoArrayListForTwoPlace(startPlace, last);
	    isListTwoPlace(startPlace, last);
	}
	sqliteAdapter.close();
	if (listForTwoPlace.size() != 0) {
	    myTwoPlaceAdapter = new ListTwoPlaceAdapter(this, listForTwoPlace);
	    return true;
	}
	return false;

    }

    private void isListTwoPlace(String first, String last) {
	for (int i = 0; i < listForFirst.size(); i++) {
	    BusHolder firstBus = listForFirst.get(i);
	    String[] arrayPlace;
	    if (firstBus.getNumberOfRoate() == 0) {
		String routeToFind = firstBus.getBus().getBusGo();
		arrayPlace = routeToFind.split("-");
	    } else {
		String routeToFind = standardizeRoute(firstBus.getRouteToFind());
		int position = routeToFind.indexOf(first);
		String stringArrayGo = firstBus.getRouteToFind().substring(
			position + first.length());
		arrayPlace = stringArrayGo.split("-");
	    }

	    // arrayPlace = firstBus.getRoute().split("-");
	    if (arrayPlace.length == 0)
		continue;
	    for (int j = 0; j < listForLast.size(); j++) {
		ArrayList<String> allPlaceChange = new ArrayList<String>();
		for (int k = 0; k < arrayPlace.length; k++) {
		    String keyPlace = arrayPlace[k];
		    keyPlace = keyPlace.trim();
		    String keyPlaceToFind = keyPlace.toLowerCase();
		    keyPlaceToFind = standardizeRoute(keyPlaceToFind);
		    Log.i("KEY PLACE", keyPlace);
		    Log.i("KEY PLACE TO FIND", keyPlaceToFind);
		    BusHolder lastBus = listForLast.get(j);
		    String routeLastToFind;
		    if (lastBus.getNumberOfRoate() == 0) {
			routeLastToFind = standardizeRoute(lastBus.getBus()
				.getBusGo());
		    } else {
			String route = standardizeRoute(lastBus
				.getRouteToFind());
			Log.i("LENGTH", String.valueOf(route.length()));
			int position = route.indexOf(last);
			Log.i("POSITION", String.valueOf(position));
			routeLastToFind = route.substring(0, position);
		    }
		    // routeLastToFind = lastBus.getRouteToFind();
		    if (check(keyPlaceToFind, routeLastToFind)) {
			allPlaceChange.add(keyPlace);
		    }
		}
		if (allPlaceChange.size() != 0) {
		    listForTwoPlace.add(new BusTwoRouteInfo(listForFirst.get(i)
			    .getBus(), listForLast.get(j).getBus(),
			    allPlaceChange));
		}
	    }

	}

    }

    private void createTwoArrayListForTwoPlace(String first, String last) {
	// TODO Auto-generated method stub
	if (listForFirst.size() != 0) {
	    listForFirst.clear();
	} else {
	    listForFirst = new ArrayList<BusHolder>();
	}
	if (listForLast.size() != 0) {
	    listForLast.clear();
	} else {
	    listForLast = new ArrayList<BusHolder>();
	}
	try {
	    mCursor.moveToFirst();

	    do {
		String go = standardizeRoute(mCursor.getString(iGoBus));
		String back = standardizeRoute(mCursor.getString(iBackBus));
		int numberOfRouteFirst = -2;
		boolean isGoFirst = check(first, go);
		boolean isBackFirst = check(first, back);
		if (isGoFirst && isBackFirst) {
		    numberOfRouteFirst = 0;
		} else if (isGoFirst) {
		    numberOfRouteFirst = -1;
		} else if (isBackFirst) {
		    numberOfRouteFirst = 1;
		}
		if (numberOfRouteFirst != -2) {
		    listForFirst.add(new BusHolder(numberOfRouteFirst,
			    new BusInfo(mCursor.getInt(iNumber), mCursor
				    .getString(iName), mCursor
				    .getString(iGoBus), mCursor
				    .getString(iBackBus), mCursor
				    .getString(iTimeStartBus), mCursor
				    .getString(iTimeEndBus), mCursor
				    .getString(iFrequency), mCursor
				    .getString(iValue), mCursor
				    .getString(iOrdinateGo), mCursor
				    .getString(iOrdinateBack))));
		} else {
		    int numberOfRouteLast = -2;
		    boolean isGoLast = check(last, go);
		    boolean isBackLast = check(last, back);
		    if (isGoLast && isBackLast) {
			numberOfRouteLast = 0;
		    } else if (isGoLast) {
			numberOfRouteLast = -1;
		    } else if (isBackLast) {
			numberOfRouteLast = 1;
		    }
		    if (numberOfRouteLast != -2) {
			listForLast.add(new BusHolder(numberOfRouteLast,
				new BusInfo(mCursor.getInt(iNumber), mCursor
					.getString(iName), mCursor
					.getString(iGoBus), mCursor
					.getString(iBackBus), mCursor
					.getString(iTimeStartBus), mCursor
					.getString(iTimeEndBus), mCursor
					.getString(iFrequency), mCursor
					.getString(iValue), mCursor
					.getString(iOrdinateGo), mCursor
					.getString(iOrdinateBack))));
		    }
		}
		mCursor.moveToNext();
	    } while (!mCursor.isAfterLast());

	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}

    }

    private String standardizeInput(String input) {
	input = input.toLowerCase();
	input = Convert.convert(input);
	return input;
    }

    private String standardizeRoute(String input) {
	input = input.toLowerCase();
	input = Convert.convertRoute(input);
	return input;
    }

    private boolean check(String input, String output) {
	int n = input.length();
	int m = output.length();
	for (int i = 0; i < m - n + 1; i++) {
	    String s = output.substring(i, i + n);
	    if (s.equals(input))
		return true;
	}
	return false;
    }

    private void loadDataFromDatabase() {

	sqliteAdapter = new SQLiteAdapter(this);
	try {
	    sqliteAdapter.close();
	    sqliteAdapter.copyDataBase();
	    sqliteAdapter.openDataBase();

	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    Log.i("DATABASE", "Cannot connect to database");
	}

	try {
	    mCursor = sqliteAdapter.rawAll();
	    initialzeIndexForBusTable();
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
	if (item.getItemId() == android.R.id.home) {
	    finish();
	}
	return super.onOptionsItemSelected(item);
    }

    private void initialzeIndexForBusTable() {
	iNumber = mCursor.getColumnIndex(columnsBus[0]);
	iGoBus = mCursor.getColumnIndex(columnsBus[1]);
	iBackBus = mCursor.getColumnIndex(columnsBus[2]);
	iName = mCursor.getColumnIndex(columnsBus[3]);
	iTimeStartBus = mCursor.getColumnIndex(columnsBus[4]);
	iTimeEndBus = mCursor.getColumnIndex(columnsBus[5]);
	iFrequency = mCursor.getColumnIndex(columnsBus[6]);
	iValue = mCursor.getColumnIndex(columnsBus[7]);
	iOrdinateGo = mCursor.getColumnIndex(columnsBus[8]);
	iOrdinateBack = mCursor.getColumnIndex(columnsBus[9]);
    }

    private class FindOneAsynTask extends AsyncTask<String, Integer, String> {

	private Context mContext;
	private boolean isFinded;
	private ProgressDialog dialog;

	public FindOneAsynTask(Context context) {
	    this.mContext = context;
	    Log.i("TAG", "Contructor");
	}

	@Override
	protected void onPreExecute() {
	    // TODO Auto-generated method stub
	    super.onPreExecute();
	    this.dialog = new ProgressDialog(mContext);
	    this.dialog.setMessage("Loading.....");
	    this.dialog.show();

	}

	@Override
	protected String doInBackground(String... arg0) {
	    // TODO Auto-generated method stub
	    isFinded = findBus();
	    return null;
	}

	@Override
	protected void onPostExecute(String result) {
	    // TODO Auto-generated method stub
	    super.onPostExecute(result);
	    if (dialog.isShowing()) {
		dialog.dismiss();
	    }
	    if (isFinded) {
		ListBusForSearchToPlace.isOneRoute = true;
		ListBusForSearchToPlace.busAdapter = myBusAdapter;
		startActivity(new Intent(mContext,
			ListBusForSearchToPlace.class));
		overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
	    } else {
		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		builder.setTitle(getString(R.string.announce));
		builder.setMessage(getString(R.string.not_find_and_require_find_two_place));
		builder.setPositiveButton("OK",
			new DialogInterface.OnClickListener() {

			    public void onClick(DialogInterface arg0, int arg1) {
				// TODO Auto-generated method stub

				FindTwoAsynTask taskFindTwo = new FindTwoAsynTask(
					mContext);
				taskFindTwo.execute("FindTwo");

			    }
			});
		builder.setNegativeButton(getString(R.string.cancel),
			new DialogInterface.OnClickListener() {

			    public void onClick(DialogInterface arg0, int arg1) {
				// TODO Auto-generated method stub
				sqliteAdapter.close();
			    }
			});
		builder.setCancelable(false);
		builder.show();
	    }

	}

    }

    public class FindTwoAsynTask extends AsyncTask<String, Integer, String> {

	private Context mContext;
	private boolean isFinded;
	private ProgressDialog dialog;

	public FindTwoAsynTask(Context context) {
	    this.mContext = context;
	    Log.i("TAG", "Contructor");
	}

	@Override
	protected void onPreExecute() {
	    // TODO Auto-generated method stub
	    super.onPreExecute();
	    this.dialog = new ProgressDialog(mContext);
	    this.dialog.setMessage("Loading.....");
	    this.dialog.show();

	}

	@Override
	protected String doInBackground(String... arg0) {
	    // TODO Auto-generated method stub
	    isFinded = findTwoRoute();
	    return null;
	}

	@Override
	protected void onPostExecute(String result) {
	    // TODO Auto-generated method stub
	    super.onPostExecute(result);
	    if (dialog.isShowing()) {
		dialog.dismiss();
	    }
	    if (isFinded) {
		ListBusForSearchToPlace.isOneRoute = false;
		Log.i("KQ", "CO TIM DUOC");
		ListBusForSearchToPlace.busTwoPlaceAdapter = myTwoPlaceAdapter;
		startActivity(new Intent(mContext,
			ListBusForSearchToPlace.class));
		overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);

	    } else {
		DialogMessage dialogMessage = new DialogMessage(mContext,
			getString(R.string.not_find_two_place));
		dialogMessage.show(false);
	    }

	}

    }
}
